using System.Text.Json;
using WeatherSystem.API.Models;
using WeatherSystem.API.Services;

namespace WeatherSystem.API.Helpers
{
    /// <summary>
    /// 动态指标数据处理帮助类
    /// </summary>
    public static class MetricsHelper
    {
        /// <summary>
        /// 将动态指标字典序列化为JSON字符串
        /// </summary>
        /// <param name="metrics">指标字典</param>
        /// <returns>JSON字符串</returns>
        public static string? SerializeMetrics(Dictionary<string, object>? metrics)
        {
            if (metrics == null || !metrics.Any())
                return null;

            try
            {
                return JsonSerializer.Serialize(metrics, new JsonSerializerOptions
                {
                    PropertyNamingPolicy = JsonNamingPolicy.CamelCase,
                    WriteIndented = false
                });
            }
            catch (Exception)
            {
                return null;
            }
        }

        /// <summary>
        /// 从JSON字符串反序列化为动态指标字典
        /// </summary>
        /// <param name="json">JSON字符串</param>
        /// <returns>指标字典</returns>
        public static Dictionary<string, object> DeserializeMetrics(string? json)
        {
            if (string.IsNullOrWhiteSpace(json))
                return new Dictionary<string, object>();

            try
            {
                var result = JsonSerializer.Deserialize<Dictionary<string, JsonElement>>(json, new JsonSerializerOptions
                {
                    PropertyNamingPolicy = JsonNamingPolicy.CamelCase
                });

                if (result == null)
                    return new Dictionary<string, object>();

                // 转换JsonElement为适当的类型
                var metrics = new Dictionary<string, object>();
                foreach (var kvp in result)
                {
                    metrics[kvp.Key] = ConvertJsonElement(kvp.Value);
                }

                return metrics;
            }
            catch (Exception)
            {
                return new Dictionary<string, object>();
            }
        }

        /// <summary>
        /// 将JsonElement转换为适当的.NET类型
        /// </summary>
        private static object ConvertJsonElement(JsonElement element)
        {
            return element.ValueKind switch
            {
                JsonValueKind.String => element.GetString() ?? string.Empty,
                JsonValueKind.Number => element.TryGetDecimal(out var d) ? d : element.GetDouble(),
                JsonValueKind.True => true,
                JsonValueKind.False => false,
                JsonValueKind.Null => null!,
                JsonValueKind.Array => element.EnumerateArray().Select(ConvertJsonElement).ToList(),
                JsonValueKind.Object => element.EnumerateObject().ToDictionary(
                    p => p.Name,
                    p => ConvertJsonElement(p.Value)
                ),
                _ => element.ToString()
            };
        }

        /// <summary>
        /// 计算动态指标的统计数据
        /// </summary>
        /// <param name="extendedMetricsList">扩展指标数据列表</param>
        /// <param name="enabledMetrics">启用的指标定义列表</param>
        /// <returns>统计指标字典</returns>
        public static Dictionary<string, object> CalculateExtendedStatistics(
            List<Dictionary<string, object>> extendedMetricsList, 
            List<Models.MetricDefinition> enabledMetrics)
        {
            var result = new Dictionary<string, object>();

            if (!extendedMetricsList.Any() || !enabledMetrics.Any())
                return result;

            foreach (var metricDefinition in enabledMetrics)
            {
                try
                {
                    var metricKey = metricDefinition.Key;
                    var dataType = metricDefinition.DataType.ToLower();

                    if (dataType == "decimal" || dataType == "int" || dataType == "double" || dataType == "float")
                    {
                        var values = new List<decimal>();
                        
                        // 从每个指标数据记录中提取指标值
                        foreach (var metrics in extendedMetricsList)
                        {
                            if (metrics.TryGetValue(metricKey, out var value) && 
                                TryConvertToDecimal(value, out var decimalValue))
                            {
                                values.Add(decimalValue);
                            }
                        }

                        if (values.Any())
                        {
                            // 计算统计值
                            result[$"avg{ToPascalCase(metricKey)}"] = Math.Round(values.Average(), 2);
                            result[$"max{ToPascalCase(metricKey)}"] = values.Max();
                            result[$"min{ToPascalCase(metricKey)}"] = values.Min();
                        }
                    }
                    else if (dataType == "string")
                    {
                        var stringValues = new List<string>();
                        
                        foreach (var metrics in extendedMetricsList)
                        {
                            if (metrics.TryGetValue(metricKey, out var value) && 
                                value is string str && !string.IsNullOrEmpty(str))
                            {
                                stringValues.Add(str);
                            }
                        }
                        
                        if (stringValues.Any())
                        {
                            var dominant = stringValues
                                .GroupBy(x => x)
                                .OrderByDescending(g => g.Count())
                                .First().Key;
                            result[$"dominant{ToPascalCase(metricKey)}"] = dominant;
                        }
                    }
                }
                catch (Exception)
                {
                    // 忽略单个指标的计算错误，继续处理其他指标
                    continue;
                }
            }

            return result;
        }


        /// <summary>
        /// 尝试将对象转换为decimal
        /// </summary>
        private static bool TryConvertToDecimal(object value, out decimal result)
        {
            result = 0;

            if (value == null)
                return false;

            if (value is decimal d)
            {
                result = d;
                return true;
            }

            if (value is double db)
            {
                result = (decimal)db;
                return true;
            }

            if (value is float f)
            {
                result = (decimal)f;
                return true;
            }

            if (value is int i)
            {
                result = i;
                return true;
            }

            if (value is long l)
            {
                result = l;
                return true;
            }

            return decimal.TryParse(value.ToString(), out result);
        }

        /// <summary>
        /// 将camelCase转换为PascalCase
        /// </summary>
        public static string ToPascalCase(string input)
        {
            if (string.IsNullOrEmpty(input))
                return input;

            return char.ToUpper(input[0]) + input.Substring(1);
        }

        /// <summary>
        /// 验证指标值的有效性
        /// </summary>
        /// <param name="metricKey">指标键</param>
        /// <param name="value">指标值</param>
        /// <param name="metricDefinitions">指标定义列表</param>
        /// <returns>是否有效</returns>
        public static bool ValidateMetricValue(string metricKey, object value, IEnumerable<Models.MetricDefinition> metricDefinitions)
        {
            var definition = metricDefinitions.FirstOrDefault(m => m.Key == metricKey);
            if (definition == null)
                return false;

            try
            {
                // 基于数据类型验证
                switch (definition.DataType?.ToLower())
                {
                    case "decimal":
                    case "number":
                        if (!TryConvertToDecimal(value, out var decimalValue))
                            return false;
                        
                        // 检查范围
                        if (!string.IsNullOrEmpty(definition.ValidationRules))
                        {
                            try
                            {
                                var rules = JsonSerializer.Deserialize<Dictionary<string, object>>(definition.ValidationRules);
                                if (rules != null)
                                {
                                    if (rules.TryGetValue("MinValue", out var minObj) && decimal.TryParse(minObj.ToString(), out var minValue) && decimalValue < minValue)
                                        return false;
                                    if (rules.TryGetValue("MaxValue", out var maxObj) && decimal.TryParse(maxObj.ToString(), out var maxValue) && decimalValue > maxValue)
                                        return false;
                                }
                            }
                            catch
                            {
                                // 忽略JSON解析错误，继续验证
                            }
                        }
                        break;

                    case "string":
                        if (value is not string stringValue)
                            return false;
                        
                        if (!string.IsNullOrEmpty(definition.ValidationRules))
                        {
                            try
                            {
                                var rules = JsonSerializer.Deserialize<Dictionary<string, object>>(definition.ValidationRules);
                                if (rules != null && rules.TryGetValue("MaxLength", out var maxLengthObj) && 
                                    int.TryParse(maxLengthObj.ToString(), out var maxLength) && 
                                    stringValue.Length > maxLength)
                                    return false;
                            }
                            catch
                            {
                                // 忽略JSON解析错误，继续验证
                            }
                        }
                        break;

                    case "boolean":
                        if (value is not bool)
                            return false;
                        break;

                    default:
                        return true; // 未知类型默认通过
                }

                return true;
            }
            catch (Exception)
            {
                return false;
            }
        }
    }
}